package com.shrct.businessprocess.purchase.impl;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.shrct.businessprocess.budget.BudgetType;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.budget.RCBudgetStatus;
import com.shrct.businessprocess.budget.RCBudgetTaskStatus;
import com.shrct.businessprocess.budget.RCCost4ACTItem;
import com.shrct.businessprocess.budget.RCCostBreakDown;
import com.shrct.businessprocess.budget.RCDirectCostRequest;
import com.shrct.businessprocess.budget.RCHasCostBudgetCostRequest;
import com.shrct.businessprocess.diagnose.DiagnoseItem;
import com.shrct.businessprocess.diagnose.IDiagnoseAcceptor;
import com.shrct.businessprocess.money.Moneys;
import com.shrct.businessprocess.product.RCProductMetaType;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.project.RCExchangeRate;
import com.shrct.businessprocess.project.RCProjectMoney;
import com.shrct.businessprocess.purchase.RCAnonymousContractProductItem;
import com.shrct.businessprocess.purchase.RCAnonymousProductPurchaseBudget;
import com.shrct.businessprocess.purchase.RCBaseProductPurchaseBudget;
import com.shrct.businessprocess.purchase.RCBasePurchaseOrder;
import com.shrct.businessprocess.purchase.RCBasePurchaseRequest;
import com.shrct.businessprocess.purchase.RCBudgetContract;
import com.shrct.businessprocess.purchase.RCBudgetContractItem;
import com.shrct.businessprocess.purchase.RCProductPurchaseRequest;
import com.shrct.businessprocess.purchase.RCProductPurchaseRequestItem;
import com.shrct.businessprocess.purchase.RCTransforCostPayRequest;
import com.shrct.businessprocess.purchase.impl.RCBaseProductPurchaseBudgetImpl;
import com.shrct.businessprocess.purchase.proxy.RCAnonymousProductPurchaseBudgetProxy;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

@Entity
@DiscriminatorValue("RCANONYMOUSPRODUCTPURCHASEBUDGET_TYPE")
public class RCAnonymousProductPurchaseBudgetImpl extends RCBaseProductPurchaseBudgetImpl implements RCAnonymousProductPurchaseBudget {
  public RCAnonymousProductPurchaseBudgetImpl() {
    super();
  }
  
  public RCAnonymousProductPurchaseBudgetImpl(final RCCostBreakDown cbd) {
    super( cbd);
    
  }
  
  @Embedded
  @AttributeOverrides(value = { @AttributeOverride(name = "amount", column = @Column(name = "netPrice_amount") ), @AttributeOverride(name = "workaround", column = @Column(name = "netPrice_workaround") ) } )
  @AssociationOverrides(value = @AssociationOverride(name = "exchange", joinColumns = @JoinColumn(name = "netPrice_exchange") ) )
  private RCProjectMoney netPrice = com.shrct.businessprocess.project.RCProjectMoney.create();
  
  public RCProjectMoney getNetPrice() {
    return this.netPrice;
  }
  
  public RCAnonymousProductPurchaseBudget setNetPrice(final RCProjectMoney netPrice) {
    this.netPrice = netPrice;
    return this;			
    
  }
  
  private Double netTaxRate;
  
  public Double getNetTaxRate() {
    return this.netTaxRate;
  }
  
  public RCAnonymousProductPurchaseBudget setNetTaxRate(final Double netTaxRate) {
    this.netTaxRate = netTaxRate;
    return this;			
    
  }
  
  public String getName() {
    return "\u8017\u6750";
  }
  
  public RCProjectMoney getContractPrice() {
    RCProjectMoney _rCProjectMoney = new RCProjectMoney();
    final Procedure1<RCProjectMoney> _function = new Procedure1<RCProjectMoney>() {
        public void apply(final RCProjectMoney it) {
          it.setAmount(Double.valueOf(0d));
          RCCostBreakDown _cbd = RCAnonymousProductPurchaseBudgetImpl.this.getCbd();
          RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
          it.setExchange(_exchangeRate);
        }
      };
    RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function);
    return _doubleArrow;
  }
  
  public Double getContractTaxRate() {
    return Double.valueOf(0d);
  }
  
  public RCExchangeRate getDefaultContractExchangeRate() {
    RCCostBreakDown _cbd = this.getCbd();
    RCExchangeRate _exchangeRate = _cbd.getExchangeRate();
    return _exchangeRate;
  }
  
  public String getEntityName() {
    BudgetType _budgetType = this.getBudgetType();
    String _name = _budgetType.getName();
    return _name;
  }
  
  public Boolean seemsFinished() {
    boolean _xifexpression = false;
    RCBudgetStatus _budgetStatus = this.getBudgetStatus();
    boolean _equals = Objects.equal(_budgetStatus, RCBudgetStatus.unset);
    if (_equals) {
      _xifexpression = false;
    } else {
      RCBudgetStatus _budgetStatus_1 = this.getBudgetStatus();
      boolean _equals_1 = Objects.equal(_budgetStatus_1, RCBudgetStatus.finished);
      _xifexpression = _equals_1;
    }
    return Boolean.valueOf(_xifexpression);
  }
  
  public RCBudgetTaskStatus getBudgetTaskStatus() {
    RCBudgetTaskStatus _xifexpression = null;
    Double _amount = this.netPrice.getAmount();
    boolean _equals = ((_amount).doubleValue() == 0d);
    if (_equals) {
      _xifexpression = RCBudgetTaskStatus.unknown;
    } else {
      RCBudgetTaskStatus _xifexpression_1 = null;
      Boolean _seemsFinished = this.seemsFinished();
      if ((_seemsFinished).booleanValue()) {
        _xifexpression_1 = RCBudgetTaskStatus.finished;
      } else {
        _xifexpression_1 = RCBudgetTaskStatus.unfinished;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public String getTypeId() {
    return "RCAZBudget";
  }
  
  public void purchaseRequestAuditPassed(final RCProductPurchaseRequest purchaseRequest) {
    final RCAnonymousProductPurchaseBudgetImpl b = this;
    Collection<RCBudgetContract> _contracts = b.getContracts();
    final Procedure1<RCBudgetContract> _function = new Procedure1<RCBudgetContract>() {
        public void apply(final RCBudgetContract contract) {
          Collection<RCProductPurchaseRequestItem> _items = purchaseRequest.getItems();
          final Procedure1<RCProductPurchaseRequestItem> _function = new Procedure1<RCProductPurchaseRequestItem>() {
              public void apply(final RCProductPurchaseRequestItem requestItem) {
                Collection<RCBudgetContractItem> _contratItems = contract.getContratItems();
                final Function1<RCBudgetContractItem,Boolean> _function = new Function1<RCBudgetContractItem,Boolean>() {
                    public Boolean apply(final RCBudgetContractItem it) {
                      RCProductSpecification _productSpec = it.getProductSpec();
                      RCProductSpecification _productSpec_1 = requestItem.getProductSpec();
                      boolean _equals = Objects.equal(_productSpec, _productSpec_1);
                      return Boolean.valueOf(_equals);
                    }
                  };
                boolean _exists = IterableExtensions.<RCBudgetContractItem>exists(_contratItems, _function);
                boolean _not = (!_exists);
                if (_not) {
                  RCAnonymousContractProductItem _createAnonymouseProductItem = contract.createAnonymouseProductItem();
                  final Procedure1<RCAnonymousContractProductItem> _function_1 = new Procedure1<RCAnonymousContractProductItem>() {
                      public void apply(final RCAnonymousContractProductItem contractItem) {
                        RCProductSpecification _productSpec = requestItem.getProductSpec();
                        contractItem.setProductSpec(_productSpec);
                        RCProjectMoney _rCProjectMoney = new RCProjectMoney();
                        final Procedure1<RCProjectMoney> _function = new Procedure1<RCProjectMoney>() {
                            public void apply(final RCProjectMoney it) {
                              it.setAmount(Double.valueOf(0d));
                              RCExchangeRate _defaultContractExchangeRate = b.getDefaultContractExchangeRate();
                              it.setExchange(_defaultContractExchangeRate);
                            }
                          };
                        RCProjectMoney _doubleArrow = ObjectExtensions.<RCProjectMoney>operator_doubleArrow(_rCProjectMoney, _function);
                        contractItem.setPrice(_doubleArrow);
                        contractItem.setQuantity(Integer.valueOf(0));
                      }
                    };
                  ObjectExtensions.<RCAnonymousContractProductItem>operator_doubleArrow(_createAnonymouseProductItem, _function_1);
                }
              }
            };
          IterableExtensions.<RCProductPurchaseRequestItem>forEach(_items, _function);
        }
      };
    IterableExtensions.<RCBudgetContract>forEach(_contracts, _function);
  }
  
  public RCProductMetaType getProductMetaType() {
    return RCProductMetaType.anonymous;
  }
  
  public Iterable<RCCost4ACTItem> getCost4ACItems() {
    Iterable<RCCost4ACTItem> _xblockexpression = null;
    {
      Collection<RCHasCostBudgetCostRequest> _costRequests = this.getCostRequests();
      Iterable<RCDirectCostRequest> _filter = Iterables.<RCDirectCostRequest>filter(_costRequests, RCDirectCostRequest.class);
      final Function1<RCDirectCostRequest,Iterable<RCCost4ACTItem>> _function = new Function1<RCDirectCostRequest,Iterable<RCCost4ACTItem>>() {
          public Iterable<RCCost4ACTItem> apply(final RCDirectCostRequest it) {
            Iterable<RCCost4ACTItem> _cost4ACItems = it.getCost4ACItems();
            return _cost4ACItems;
          }
        };
      Iterable<Iterable<RCCost4ACTItem>> _map = IterableExtensions.<RCDirectCostRequest, Iterable<RCCost4ACTItem>>map(_filter, _function);
      final Iterable<RCCost4ACTItem> directCosts = Iterables.<RCCost4ACTItem>concat(_map);
      Collection<RCBasePurchaseRequest> _purchaseRequests = this.getPurchaseRequests();
      final Function1<RCBasePurchaseRequest,Boolean> _function_1 = new Function1<RCBasePurchaseRequest,Boolean>() {
          public Boolean apply(final RCBasePurchaseRequest it) {
            Boolean _isPassed = it.getIsPassed();
            return _isPassed;
          }
        };
      Iterable<RCBasePurchaseRequest> _filter_1 = IterableExtensions.<RCBasePurchaseRequest>filter(_purchaseRequests, _function_1);
      final Function1<RCBasePurchaseRequest,Collection<? extends RCBasePurchaseOrder>> _function_2 = new Function1<RCBasePurchaseRequest,Collection<? extends RCBasePurchaseOrder>>() {
          public Collection<? extends RCBasePurchaseOrder> apply(final RCBasePurchaseRequest it) {
            Collection<? extends RCBasePurchaseOrder> _purchaseOrders = it.getPurchaseOrders();
            return _purchaseOrders;
          }
        };
      Iterable<Collection<? extends RCBasePurchaseOrder>> _map_1 = IterableExtensions.<RCBasePurchaseRequest, Collection<? extends RCBasePurchaseOrder>>map(_filter_1, _function_2);
      Iterable<? extends RCBasePurchaseOrder> _flatten = Iterables.concat(_map_1);
      final Function1<RCBasePurchaseOrder,Boolean> _function_3 = new Function1<RCBasePurchaseOrder,Boolean>() {
          public Boolean apply(final RCBasePurchaseOrder it) {
            Boolean _isInitialized = it.getIsInitialized();
            return _isInitialized;
          }
        };
      Iterable<? extends RCBasePurchaseOrder> orders = IterableExtensions.filter(_flatten, _function_3);
      final Function1<RCBasePurchaseOrder,Iterable<RCCost4ACTItem>> _function_4 = new Function1<RCBasePurchaseOrder,Iterable<RCCost4ACTItem>>() {
          public Iterable<RCCost4ACTItem> apply(final RCBasePurchaseOrder it) {
            Iterable<RCCost4ACTItem> _cost4ACItems = it.getCost4ACItems();
            return _cost4ACItems;
          }
        };
      Iterable<Iterable<RCCost4ACTItem>> _map_2 = IterableExtensions.map(orders, _function_4);
      Iterable<RCCost4ACTItem> _flatten_1 = Iterables.<RCCost4ACTItem>concat(_map_2);
      ArrayList<Iterable<RCCost4ACTItem>> _newArrayList = CollectionLiterals.<Iterable<RCCost4ACTItem>>newArrayList(_flatten_1, directCosts);
      final Iterable<RCCost4ACTItem> c1 = Iterables.<RCCost4ACTItem>concat(_newArrayList);
      Collection<RCTransforCostPayRequest> _transforCostPayRequest = this.getTransforCostPayRequest();
      final Function1<RCTransforCostPayRequest,Iterable<RCCost4ACTItem>> _function_5 = new Function1<RCTransforCostPayRequest,Iterable<RCCost4ACTItem>>() {
          public Iterable<RCCost4ACTItem> apply(final RCTransforCostPayRequest it) {
            Iterable<RCCost4ACTItem> _cost4ACItems = it.getCost4ACItems();
            return _cost4ACItems;
          }
        };
      Iterable<Iterable<RCCost4ACTItem>> _map_3 = IterableExtensions.<RCTransforCostPayRequest, Iterable<RCCost4ACTItem>>map(_transforCostPayRequest, _function_5);
      final Iterable<RCCost4ACTItem> c3 = Iterables.<RCCost4ACTItem>concat(_map_3);
      ArrayList<Iterable<RCCost4ACTItem>> _newArrayList_1 = CollectionLiterals.<Iterable<RCCost4ACTItem>>newArrayList(c1, c3);
      final Iterable<RCCost4ACTItem> result = Iterables.<RCCost4ACTItem>concat(_newArrayList_1);
      final Procedure1<RCCost4ACTItem> _function_6 = new Procedure1<RCCost4ACTItem>() {
          public void apply(final RCCost4ACTItem it) {
            it.setBudget(RCAnonymousProductPurchaseBudgetImpl.this);
          }
        };
      IterableExtensions.<RCCost4ACTItem>forEach(result, _function_6);
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public void diagnose(final IDiagnoseAcceptor acceptor) {
    super.diagnose(acceptor);
    Double thisAmount = this.netPrice.toHostAmount();
    RCCostBreakDown _cbd = this.getCbd();
    Collection<RCBudget> _budgets = _cbd.getBudgets();
    Iterable<RCBaseProductPurchaseBudget> _filter = Iterables.<RCBaseProductPurchaseBudget>filter(_budgets, RCBaseProductPurchaseBudget.class);
    final Function1<RCBaseProductPurchaseBudget,RCProjectMoney> _function = new Function1<RCBaseProductPurchaseBudget,RCProjectMoney>() {
        public RCProjectMoney apply(final RCBaseProductPurchaseBudget it) {
          RCProjectMoney _contractPrice = it.getContractPrice();
          return _contractPrice;
        }
      };
    Iterable<RCProjectMoney> _map = IterableExtensions.<RCBaseProductPurchaseBudget, RCProjectMoney>map(_filter, _function);
    RCExchangeRate _defaultContractExchangeRate = this.getDefaultContractExchangeRate();
    RCProjectMoney _sum = Moneys.sum(_map, _defaultContractExchangeRate);
    Double productAmount = _sum.toHostAmount();
    boolean _xifexpression = false;
    boolean _lessEqualsThan = ((productAmount).doubleValue() <= 100000d);
    if (_lessEqualsThan) {
      boolean _equals = ((thisAmount).doubleValue() == 0);
      _xifexpression = _equals;
    } else {
      boolean _xifexpression_1 = false;
      boolean _and = false;
      boolean _greaterThan = ((productAmount).doubleValue() > 100000d);
      if (!_greaterThan) {
        _and = false;
      } else {
        boolean _lessEqualsThan_1 = ((productAmount).doubleValue() <= 500000d);
        _and = (_greaterThan && _lessEqualsThan_1);
      }
      if (_and) {
        boolean _lessThan = ((thisAmount).doubleValue() < 2000d);
        _xifexpression_1 = _lessThan;
      } else {
        double _divide = (0.5 / 100);
        double _multiply = ((productAmount).doubleValue() * _divide);
        boolean _lessEqualsThan_2 = ((thisAmount).doubleValue() <= _multiply);
        _xifexpression_1 = _lessEqualsThan_2;
      }
      _xifexpression = _xifexpression_1;
    }
    boolean isValid = _xifexpression;
    boolean _not = (!isValid);
    if (_not) {
      DiagnoseItem _diagnoseItem = new DiagnoseItem();
      final Procedure1<DiagnoseItem> _function_1 = new Procedure1<DiagnoseItem>() {
          public void apply(final DiagnoseItem it) {
            it.setMessage("\u8017\u6750\u91D1\u989D\u8D85\u6807");
          }
        };
      DiagnoseItem _doubleArrow = ObjectExtensions.<DiagnoseItem>operator_doubleArrow(_diagnoseItem, _function_1);
      acceptor.accept(_doubleArrow);
    }
  }
  
  public static RCAnonymousProductPurchaseBudget create(final RCCostBreakDown cbd, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.purchase.RCAnonymousProductPurchaseBudget rCAnonymousProductPurchaseBudget = new com.shrct.businessprocess.purchase.impl.RCAnonymousProductPurchaseBudgetImpl(
    	cbd
    );
    objectFactory.create(rCAnonymousProductPurchaseBudget);
    return rCAnonymousProductPurchaseBudget;			
    
  }
  
  public static RCAnonymousProductPurchaseBudget createRCAnonymousProductPurchaseBudgetImpl(final RCCostBreakDown cbd, final IObjectFactory objectFactory, final Procedure1<RCAnonymousProductPurchaseBudget> init) {
    com.shrct.businessprocess.purchase.RCAnonymousProductPurchaseBudget rCAnonymousProductPurchaseBudget = new com.shrct.businessprocess.purchase.impl.RCAnonymousProductPurchaseBudgetImpl(
    	cbd
    );
    objectFactory.create(rCAnonymousProductPurchaseBudget);
    init.apply(rCAnonymousProductPurchaseBudget);
    
    return rCAnonymousProductPurchaseBudget;			
    
  }
  
  public RCAnonymousProductPurchaseBudgetProxy toProxy() {
    com.shrct.businessprocess.purchase.proxy.RCAnonymousProductPurchaseBudgetProxy proxy = new com.shrct.businessprocess.purchase.proxy.RCAnonymousProductPurchaseBudgetProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
